home *** CD-ROM | disk | FTP | other *** search
/ Delphi Informant Complete 1995 - 2000 / Delphi Informant Complete 1995 to 2000.iso / Delphi Informant Magazine Complete Works SOURCE CODE 1995.rar / 1995 / DEC / DI9512AC / aclist.pas < prev    next >
Pascal/Delphi Source File  |  1995-08-01  |  12KB  |  537 lines

  1. unit acList;
  2.  
  3. {
  4.   Project: Non-Component Persistent Object Streaming
  5.  
  6.   Alan Ciemian
  7.   Copyright ⌐ 1995. All Rights Reserved
  8.  
  9.  
  10.   Overview
  11.   ========
  12.   Implements TacObjStringList class descended from TacStreamable.
  13.  
  14.   TacObjStringList defines a container class for TacStreamable objects.
  15.  
  16. }
  17.  
  18. interface
  19.  
  20. uses
  21.   Classes,
  22.   acStream;
  23.  
  24.  
  25. type
  26.   TacObjListIndex = Integer;  { Indexing into lists }
  27.   TacObjListCount = LongInt;  { For saving list count to stream. }
  28.  
  29. type { for TacObjStringList notifications }
  30.   TacObjListNotifyEvent = procedure (Idx: TacObjListIndex) of object;
  31.  
  32. type
  33.   TacObjStringList = class(TacStreamable)
  34.   private
  35.     FList       : TStrings;           { Ref to contained list }
  36.     FOwnList    : Boolean;            { Flag for list ownership }
  37.     FOwnObjects : Boolean;            { Flag for list item ownership }
  38.     FOnDelete   : TacObjListNotifyEvent; { Delete notification }
  39.     FOnInsert   : TacObjListNotifyEvent; { Insert notification }
  40.     procedure ResetList
  41.       (
  42.       const Strings : TStrings;
  43.       const OwnObjs : Boolean
  44.       );
  45.     procedure CloneContents(const OtherList: TacObjStringList);
  46.     procedure FreeList;
  47.     procedure FreeObjects;
  48.     { Property access methods }
  49.     function  GetCount: TacObjListIndex;
  50.   protected
  51.     { TPersistent overrides }
  52.     procedure AssignTo(Dest: TPersistent); override;
  53.     { TacStreamable overrides }
  54.     procedure InitFields; override;
  55.     procedure ReadFromStream(Stream: TacObjStream); override;
  56.     procedure SaveToStream  (Stream: TacObjStream); override;
  57.     { Protected properties }
  58.     property OnObjDelete: TacObjListNotifyEvent
  59.              read FOnDelete
  60.              write FOnDelete;
  61.     property OnObjInsert: TacObjListNotifyEvent
  62.              read FOnInsert
  63.              write FOnInsert;
  64.   public
  65.     { Construction/Destruction }
  66.     constructor Create
  67.       (
  68.       const Strings    : TStrings;
  69.       const OwnObjects : Boolean
  70.       );
  71.     destructor  Destroy; override;
  72.     { List object access }
  73.     function  AtIndex(const Idx: TacObjListIndex): TacStreamable;
  74.     function  AtName(const Name: String): TacStreamable;
  75.     { Standard list methods }
  76.     procedure BeginUpdate;
  77.     procedure EndUpdate;
  78.     function  Add(const Obj: TacStreamable): TacObjListIndex;
  79.     procedure Insert(const Idx: TacObjListIndex; const Obj: TacStreamable);
  80.     procedure Move(const FromIdx: TacObjListIndex; const ToIdx: TacObjListIndex);
  81.     { Delete's delete the objects if they are owned }
  82.     procedure DeleteIdx(const Idx: TacObjListIndex);
  83.     procedure DeleteObj(const Obj: TacStreamable);
  84.     procedure DeleteName(const Name: String);
  85.     procedure DeleteAll;
  86.     { Remove's NEVER delete the objects }
  87.     function  RemoveIdx(const Idx: TacObjListIndex): TacStreamable;
  88.     function  RemoveObj(const Obj: TacStreamable): TacStreamable;
  89.     function  RemoveName(const Name: String): TacStreamable;
  90.     { ObjStringList specific methods }
  91.     procedure UpdateObjectName(const Idx: TacObjListIndex);
  92.     { Public properties }
  93.     property Strings: TStrings
  94.              read FList;
  95.     property Count: TacObjListIndex
  96.              read GetCount;
  97.     property OwnObjects: Boolean
  98.              read FOwnObjects
  99.              write FOwnObjects;
  100.     property OwnList: Boolean
  101.              read FOwnList
  102.              write FOwnList;
  103.   end;
  104.  
  105.  
  106. implementation
  107.  
  108.  
  109. { TacObjStringList }
  110.  
  111.  
  112. {
  113. Create creates a TacObjStringList tied to a specified TStrings instance.
  114. If Strings parameter is nil, a new TStringList will be created.
  115. If OwnObjects parameter is True, list will have responsibility for
  116.   deleting contained objects.
  117. }
  118. constructor TacObjStringList.Create
  119.   (
  120.   const Strings:    TStrings;
  121.   const OwnObjects: Boolean
  122.   );
  123. begin
  124.   inherited Create;
  125.   ResetList(Strings, OwnObjects);
  126. end;
  127.  
  128.  
  129. {
  130. Destroy frees the contained objects if they are owned and
  131.   frees the list if it is owned.
  132. }
  133. destructor  TacObjStringList.Destroy;
  134. begin
  135.   FreeList;
  136.   inherited Destroy;
  137. end;
  138.  
  139.  
  140. {
  141. InitFields sets default values for member fields.
  142. }
  143. procedure TacObjStringList.InitFields;
  144. begin
  145.   inherited InitFields;
  146.   FList       := nil;
  147.   FOwnList    := False;
  148.   FOwnObjects := False;
  149. end;
  150.  
  151.  
  152. {
  153. AssignTo override allows assignment of TacObjStringList instances.
  154. Destination list will be reset to contain and own copies of the items
  155.   currently in this list. The destination instance list and list
  156.   ownership will not otherwise be changed.
  157. }
  158. procedure TacObjStringList.AssignTo
  159.   (
  160.   Dest : TPersistent
  161.   );
  162. var
  163.   DestStringList : TacObjStringList;
  164. begin
  165.   if ( Dest = self ) then Exit;
  166.  
  167.   if ( (Dest is TacObjStringList) and (Self is Dest.ClassType) ) then
  168.     begin  { Assigning to same or superclass }
  169.     DestStringList := ( Dest as TacObjStringList );
  170.     DestStringList.ResetList(DestStringList.FList, True);
  171.     DestStringList.CloneContents(self);
  172.     end
  173.   else
  174.     begin  { TPersistent will process error }
  175.     inherited AssignTo(Dest);
  176.     end;
  177. end;
  178.  
  179.  
  180. {
  181. ResetList sets the contained list and ownership flag.
  182. If the Strings parameter is nil a new TStringList is created.
  183. If the Strings parameter is assigned it becomes the contained list
  184.   and it is emptied.
  185. }
  186. procedure TacObjStringList.ResetList
  187.   (
  188.   const Strings : TStrings;
  189.   const OwnObjs : Boolean
  190.   );
  191. begin
  192.   { If changing list, free current list }
  193.   if ( Strings <> FList ) then FreeList;
  194.  
  195.   if ( Assigned(Strings) ) then
  196.     begin
  197.     FList := Strings;
  198.     end
  199.   else
  200.     begin { Create a new list }
  201.     FList := TStringList.Create;
  202.     FOwnList := True;
  203.     end;
  204.   DeleteAll;
  205.   OwnObjects := OwnObjs;
  206. end;
  207.  
  208.  
  209. {
  210. CloneContents clones all the items in another list and adds them to this list.
  211. }
  212. procedure TacObjStringList.CloneContents
  213.   (
  214.   const OtherList: TacObjStringList
  215.   );
  216. var
  217.   Idx       : TacObjListIndex;
  218.   Item      : TacStreamable;
  219.   ItemClass : TacStreamableClass;
  220. begin
  221.   for Idx := 0 to (OtherList.Count - 1) do
  222.     begin
  223.     Item      := OtherList.AtIndex(Idx);
  224.     ItemClass := TacStreamableClass(Item.ClassType);
  225.     Add(ItemClass.CreateClone(Item));
  226.     end;
  227. end;
  228.  
  229.  
  230. {
  231. FreeList frees the list reference
  232. }
  233. procedure TacObjStringList.FreeList;
  234. begin
  235.   if ( Assigned(FList) ) then
  236.     begin
  237.     if ( FOwnObjects ) then FreeObjects;
  238.     if ( FOwnList    ) then
  239.       begin
  240.       FList.Free;
  241.       FList := nil;
  242.       end;
  243.     end;
  244. end;
  245.  
  246.  
  247. {
  248. FreeObjects frees all the objects in the list.
  249. }
  250. procedure TacObjStringList.FreeObjects;
  251. var
  252.   Idx : TacObjListIndex;
  253. begin
  254.   for Idx := 0 to (Count - 1) do
  255.     begin
  256.     AtIndex(Idx).Free;
  257.     end;
  258. end;
  259.  
  260.  
  261. {
  262. ReadFromStream override resets the list and fills it from a stream image.
  263. }
  264. procedure TacObjStringList.ReadFromStream
  265.   (
  266.   Stream : TacObjStream
  267.   );
  268. var
  269.   ReadCount : TacObjListCount;
  270.   ReadIdx   : TacObjListIndex;
  271. begin
  272.   { Clear or create the list reference as needed }
  273.   ResetList(FList, True);
  274.  
  275.   { Read contained object count }
  276.   Stream.ReadBuffer(ReadCount, sizeof(ReadCount));
  277.   { Read objects }
  278.   for ReadIdx := 1 to ReadCount do
  279.     begin
  280.     Add(Stream.ReadObject(nil));
  281.     end;
  282. end;
  283.  
  284.  
  285. {
  286. SaveToStream override saves an image of the list to a stream.
  287. }
  288. procedure TacObjStringList.SaveToStream
  289.   (
  290.   Stream : TacObjStream
  291.   );
  292. var
  293.   SaveCount : TacObjListCount;
  294.   SaveIdx   : TacObjListIndex;
  295. begin
  296.   { Save contained object count }
  297.   SaveCount := Count;
  298.   Stream.SaveBuffer(SaveCount, Sizeof(SaveCount));
  299.   { Save objects }
  300.   for SaveIdx := 0 to (SaveCount - 1) do
  301.     begin
  302.     Stream.SaveObject(AtIndex(SaveIdx));
  303.     end;
  304. end;
  305.  
  306.  
  307. {
  308. AtIndex returns a reference to the object at a specific index.
  309. }
  310. function  TacObjStringList.AtIndex
  311.   (
  312.   const Idx : TacObjListIndex
  313.   ): TacStreamable;
  314. begin
  315.   Result := nil;
  316.   if ( (0 <= Idx) and (Idx < Count) ) then
  317.     begin
  318.     Result := FList.Objects[Idx] as TacStreamable;
  319.     end;
  320. end;
  321.  
  322.  
  323. {
  324. AtName returns a reference to the object with a specific name.
  325. }
  326. function  TacObjStringList.AtName
  327.   (
  328.   const Name : String
  329.   ): TacS